package com.ruoyi.xag.ysty.service.impl;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.permission.Dao.SerDevicePermi;
import com.ruoyi.permission.mapper.SerDevicePermiMapper;
import com.ruoyi.xag.domain.IotDeviceInfo;
import com.ruoyi.xag.domain.datapoints.Soil;
import com.ruoyi.xag.domain.datapoints.SoilSenorDataPoints;
import com.ruoyi.xag.domain.datapoints.Weather;
import com.ruoyi.xag.domain.datapoints.WeatherSenorDataPoints;
import com.ruoyi.xag.mapper.DeviceMapper;
import com.ruoyi.xag.ysty.domain.BusinessAndDeviceId;
import com.ruoyi.xag.ysty.domain.YSTYDeviceInfo;
import com.ruoyi.xag.ysty.mapper.YSTYDeviceMapper;
import com.ruoyi.xag.ysty.service.YSTYDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class YSTYDeviceServiceImpl implements YSTYDeviceService {


    @Autowired
    private YSTYDeviceMapper ystyDeviceMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private SerDevicePermiMapper permiMapper;



    @Value("${YSTY.url}")
    private String YSTYurl;


    @Override
    public String selectDeviceInfos(String business) {
        String result = "";
        String url = YSTYurl + "/deviceListHandler";
        HttpPost post = new HttpPost(url);
        try {
            long now = System.currentTimeMillis();
//            log.info("time:" + now);
            //装填参数
            String json =String.format("{\"version\": \"2022-08-10\",\"business\": \"%s\",\"equipment\": \"AJ0012931\",\"requestTime\": \"" + now + "\",\"format\": \"JSON\",\"value\": {\"page\": 1,\"length\": 10}}",business);
            StringEntity s = new StringEntity(json, "utf-8");

            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            //设置参数到请求对象中
            post.setEntity(s);
            //添加请求头参数
            post.setHeader("Content-type", "application/json");
            post.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            CloseableHttpClient client = HttpClients.createDefault();
            //启动执行请求，并获得返回值
            CloseableHttpResponse response = client.execute(post);
            //得到返回的entity对象
            HttpEntity entity = response.getEntity();
            //把实体对象转换为string
            result = EntityUtils.toString(entity, "UTF-8");
            //释放链接
            response.close();

        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return result;
    }

    @Override
    public int insertDeviceInfoFromYSTY(String business) throws ParseException {
        String deviceList = selectDeviceInfos(business);
        List<String> deviceIds = ystyDeviceMapper.selectAllDeviceId();
        int result = 0;
        if(deviceList !=null && deviceList.length() !=0){
            JSONObject jsonObject = JSONObject.parseObject(deviceList);
            log.info("jsonObject:" + jsonObject);
            String resultData = jsonObject.getString("data");
            resultData.replace("[","").replace("]","");
            jsonObject = JSONObject.parseObject(resultData);

            JSONArray deviceListJson = jsonObject.getJSONArray("deviceList");
            for (Object obj:deviceListJson) {
                YSTYDeviceInfo ystyDeviceInfo = new YSTYDeviceInfo();
                JSONObject dataObj = JSONObject.parseObject(obj.toString());
                String deviceId = dataObj.getString("deviceId");
                if(deviceIds.contains(deviceId)){
                    String deviceStatus = dataObj.getString("deviceStatus").equals("1")? "在线":"离线";
                    SerDevicePermi devicePermiInfo = permiMapper.selectByDeviceSerial(deviceId);
                    devicePermiInfo.setOnlineState(deviceStatus);
                    permiMapper.updateByPrimaryKeySelective(devicePermiInfo);
                    continue;
                }else {
                    SerDevicePermi devicePermiInfo = new SerDevicePermi().setDeviceSerial(deviceId);
                    ystyDeviceInfo.setDeviceId(deviceId);
                    String serial = dataObj.getString("serial");
                    ystyDeviceInfo.setSerial(serial);
                    String deviceName = dataObj.getString("deviceName");
                    ystyDeviceInfo.setDeviceName(deviceName);
                    String deviceStatus = dataObj.getString("deviceStatus");
                    String onlineState = deviceStatus.equals("1")?"在线":"离线";
                    ystyDeviceInfo.setDeviceStatus(deviceStatus);
                    Integer deviceType = dataObj.getInteger("deviceType");
                    ystyDeviceInfo.setDeviceType(deviceType);
                    Date createTime = dataObj.getDate("createTime");
                    ystyDeviceInfo.setCreateTime(createTime);
                    Date onlineTime = dataObj.getDate("onlineTime");
                    ystyDeviceInfo.setCreateTime(onlineTime);
                    Integer deviceEnable = dataObj.getInteger("enable");
                    ystyDeviceInfo.setDeviceEnable(deviceEnable);

//                    Date date = new Date();
//                    // 创建SimpleDateFormat对象，指定字符串的日期格式
//                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                    // 调用format() 方法，格式化时间，转换为指定格式字符串
//                    String now = sdf.format(date);

                    devicePermiInfo.setOnlineState(onlineState);
                    devicePermiInfo.setDeviceType("土壤设备");
                    devicePermiInfo.setTypeId(4);
                    permiMapper.insertSelective(devicePermiInfo);
                    log.info("插入信息"+ ystyDeviceInfo);
                    result++;
                    ystyDeviceMapper.insertDeviceInfo(ystyDeviceInfo);
                }
            }
        }
        return result;
    }

    /**
     * 获取设备所有属性列表
     * @param businessAndDeviceId
     * @return
     */
    @Override
    public String getDeviceElement(BusinessAndDeviceId businessAndDeviceId){
        String result = "";
        String url = YSTYurl + "/deviceElementHandler";
        HttpPost post = new HttpPost(url);
        String business = businessAndDeviceId.getBusiness();
        String deviceId = businessAndDeviceId.getDeviceId();
        try {
            long now = System.currentTimeMillis();
//            log.info("time:" + now);
            //装填参数
            String json = "{\"version\": \"2022-08-10\",\"business\": \"" + business +"\",\"requestTime\":\"" + now + "\",\"format\": \"JSON\",\"value\": {\"page\": 1,\"length\": 10,\"deviceId\":\""+deviceId+"\"}}";
            StringEntity s = new StringEntity(json, "utf-8");

            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            //设置参数到请求对象中
            post.setEntity(s);
            //添加请求头参数
            post.setHeader("Content-type", "application/json");
            post.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            CloseableHttpClient client = HttpClients.createDefault();
            //启动执行请求，并获得返回值
            CloseableHttpResponse response = client.execute(post);
            //得到返回的entity对象
            HttpEntity entity = response.getEntity();
            //把实体对象转换为string
            result = EntityUtils.toString(entity, "UTF-8");
            //释放链接
            response.close();

        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return result;
    }

    /**
     * 获取实时数据
     * @param businessAndDeviceId
     * @return
     */
    @Override
    public String getDeviceData(BusinessAndDeviceId businessAndDeviceId){
        String result = "";
        String url = YSTYurl + "/deviceDataHandler";
        HttpPost post = new HttpPost(url);
        String deviceId = businessAndDeviceId.getDeviceId();
        String business = businessAndDeviceId.getBusiness();
        try {
            long now = System.currentTimeMillis();
//            log.info("time:" + now);
            //装填参数
            String json = String.format("{\"version\": \"2022-08-10\",\"business\": \"%s\",\"requestTime\":\"" + now + "\",\"format\": \"JSON\",\"value\": {\"page\": 1,\"length\": 5,\"deviceId\":\""+deviceId+"\"}}",business);
            StringEntity s = new StringEntity(json, "utf-8");

            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            //设置参数到请求对象中
            post.setEntity(s);
            //添加请求头参数
            post.setHeader("Content-type", "application/json");
            post.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            CloseableHttpClient client = HttpClients.createDefault();
            //启动执行请求，并获得返回值`
            CloseableHttpResponse response = client.execute(post);
            //得到返回的entity对象
            HttpEntity entity = response.getEntity();
            //把实体对象转换为string
            result = EntityUtils.toString(entity, "UTF-8");
            //释放链接
            response.close();

        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return result;
    }

    /**
     * 获取设备历史数据
     * @param deviceId
     * @param startTime
     * @param endTime
     * @param elementSigns
     * @return
     */
    @Override
    public String getDeviceDataHistory(String deviceId,Long startTime,Long endTime,String elementSigns){
        String result = "";
        String url = YSTYurl + "/deviceDataListHandler";
        HttpPost post = new HttpPost(url);
        try {
            long now = System.currentTimeMillis();
//            log.info("time:" + now);
            //装填参数
            String json = String.format("{\"version\":\"2022-08-10\",\"business\":\"1684289043406\",\"requestTime\":\"%d\",\"format\":\"JSON\",\"value\":{\"page\": 1,\"length\": 5,\"deviceId\":\"%s\",\"startTime\":\"%d\",\"endTime\":\"%d\",\"elementSigns\":\"%s\"}}", now, deviceId, startTime, endTime, elementSigns);
            StringEntity s = new StringEntity(json, "utf-8");

            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            //设置参数到请求对象中
            post.setEntity(s);
            //添加请求头参数
            post.setHeader("Content-type", "application/json");
            post.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            CloseableHttpClient client = HttpClients.createDefault();
            //启动执行请求，并获得返回值
            CloseableHttpResponse response = client.execute(post);
            //得到返回的entity对象
            HttpEntity entity = response.getEntity();
            //把实体对象转换为string
            result = EntityUtils.toString(entity, "UTF-8");
            //释放链接
            response.close();

        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return result;
    }
    public List<YSTYDeviceInfo> selectAllYSTYDevice(){
        return ystyDeviceMapper.selectAllYSTYDevice();
    }
    @Override
    public int insertSoilDataPointLast(BusinessAndDeviceId businessAndDeviceId) throws IOException, ParseException {
        String deviceId = businessAndDeviceId.getDeviceId();
        String deviceData = getDeviceData(businessAndDeviceId);
        JSONObject jsonObject = JSONObject.parseObject(deviceData);
        log.info("dataJsonObject:" + jsonObject);
        String resultData = jsonObject.getString("data");
        resultData.replace("[","").replace("]","");
        jsonObject = JSONObject.parseObject(resultData);
        JSONArray deviceDataListJson = jsonObject.getJSONArray("deviceDataList");
        SoilSenorDataPoints soilSenorDataPoints = new SoilSenorDataPoints();
        IotDeviceInfo iotDeviceInfo =new IotDeviceInfo();
        iotDeviceInfo.setDeviceId(deviceId);
        SerDevicePermi devicePermiInfo = permiMapper.selectByDeviceSerial(deviceId);
        soilSenorDataPoints.setDeviceId(deviceId);
        Soil data = new Soil();
        //采集时间是统一的，所以先统一获取采集时间（设备有时会出现后面几个数据没有采集时间的问题）
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        JSONObject deviceData0 =JSONObject.parseObject(deviceDataListJson.get(0).toString());
        soilSenorDataPoints.setCreatedAt((int)(sdf.parse(deviceData0.getString("createTime")).getTime() / 1000));
//        手动判断设备的在线状态
        String onlineState = "在线";
        if(System.currentTimeMillis() - sdf.parse(deviceData0.getString("createTime")).getTime() >  86400000){
            onlineState = "离线";
        }
        iotDeviceInfo.setDeviceStatus(onlineState);
        devicePermiInfo.setOnlineState(onlineState);
//        log.info("\n deviceData0 = "+deviceDataListJson.get(0));
        for(Object obj:deviceDataListJson){
            JSONObject dataObj = JSONObject.parseObject(obj.toString());

            String sign = dataObj.getString("sign");
            switch (sign){
                case "AH1":
                    soilSenorDataPoints.setData(data.setTemperature_1(dataObj.getFloat("value")));
                    break;
                case "AH2":
                    soilSenorDataPoints.setData(data.setTemperature_2(dataObj.getFloat("value")));
                    break;
                case "AH3":
                    soilSenorDataPoints.setData(data.setTemperature_3(dataObj.getFloat("value")));
                    break;
                case "AH4":
                    soilSenorDataPoints.setData(data.setTemperature_4(dataObj.getFloat("value")));
                    break;
                case "AH5":
                    soilSenorDataPoints.setData(data.setTemperature_5(dataObj.getFloat("value")));
                    break;
                case "AI1":
                    soilSenorDataPoints.setData(data.setHumidity_1(dataObj.getFloat("value")));
                    break;
                case "AI2":
                    soilSenorDataPoints.setData(data.setHumidity_2(dataObj.getFloat("value")));
                    break;
                case "AI3":
                    soilSenorDataPoints.setData(data.setHumidity_3(dataObj.getFloat("value")));
                    break;
                case "AI4":
                    soilSenorDataPoints.setData(data.setHumidity_4(dataObj.getFloat("value")));
                    break;
                case "AI5":
                    soilSenorDataPoints.setData(data.setHumidity_5(dataObj.getFloat("value")));
                    break;
                case "CB1":
                    soilSenorDataPoints.setData(data.setBattery(dataObj.getDouble("value")));
                    iotDeviceInfo.setBattery(dataObj.getDouble("value"));
                    devicePermiInfo.setBattery(dataObj.getDouble("value"));
                default:break;
            }
        }
        soilSenorDataPoints.setData(data).setType(1);
        int i = deviceMapper.insertSoilDataPoints(soilSenorDataPoints);
        int j = deviceMapper.updateDevice(iotDeviceInfo);
        //更新所有设备表device_permi表
        permiMapper.updateByPrimaryKeySelective(devicePermiInfo);
        System.out.println("soilSenorDataPoints:" + soilSenorDataPoints + ",iotDeviceInfo:" + iotDeviceInfo);
        return i+j;
    }

    @Override
    public int insertWeatherDataPointLast(BusinessAndDeviceId businessAndDeviceId) throws ParseException {
        String deviceId = businessAndDeviceId.getDeviceId();
        String deviceData = getDeviceData(businessAndDeviceId);
        JSONObject jsonObject = JSONObject.parseObject(deviceData);
        log.info("dataJsonObject:" + jsonObject);
        String resultData = jsonObject.getString("data");
        resultData.replace("[","").replace("]","");
        jsonObject = JSONObject.parseObject(resultData);
        JSONArray deviceDataListJson = jsonObject.getJSONArray("deviceDataList");
        WeatherSenorDataPoints weatherSenorDataPoints = new WeatherSenorDataPoints();
        IotDeviceInfo iotDeviceInfo =new IotDeviceInfo();
        iotDeviceInfo.setDeviceId(deviceId);
        SerDevicePermi devicePermiInfo = permiMapper.selectByDeviceSerial(deviceId);
        weatherSenorDataPoints.setDeviceId(deviceId);
        Weather data = new Weather();
        //采集时间是统一的，所以先统一获取采集时间（设备有时会出现后面几个数据没有采集时间的问题）
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        JSONObject deviceData0 =JSONObject.parseObject(deviceDataListJson.get(0).toString());
        weatherSenorDataPoints.setCreatedAt((int)(sdf.parse(deviceData0.getString("createTime")).getTime() / 1000));
//        手动判断设备的在线状态
        String onlineState = "在线";
        if(System.currentTimeMillis() - sdf.parse(deviceData0.getString("createTime")).getTime() >  86400000){
            onlineState = "离线";
        }
        iotDeviceInfo.setDeviceStatus(onlineState);
        devicePermiInfo.setOnlineState(onlineState);
//        log.info("\n deviceData0 = "+deviceDataListJson.get(0));
        for(Object obj:deviceDataListJson){
            JSONObject dataObj = JSONObject.parseObject(obj.toString());

            String sign = dataObj.getString("sign");
            switch (sign){
                case "AA1":
                    weatherSenorDataPoints.setData(data.setTemperature(dataObj.getFloat("value")));
                    break;
                case "AB1":
                    weatherSenorDataPoints.setData(data.setHumidity(dataObj.getFloat("value")));
                    break;
                case "AC1":
                    weatherSenorDataPoints.setData(data.setPressure(dataObj.getFloat("value")));
                    break;
                case "AD1":
                    if(dataObj.getFloat("value")!=null) {
                        weatherSenorDataPoints.setData(data.setWind_speed(dataObj.getFloat("value")));
                        break;
                    }else {
                        weatherSenorDataPoints.setData(data.setWind_speed(-1.0f));
                        break;
                    }
                case "AE1":
                    if(dataObj.getFloat("value")!=null) {
                        weatherSenorDataPoints.setData(data.setWind_direction(dataObj.getFloat("value")));
                        break;
                    }else {
                        weatherSenorDataPoints.setData(data.setWind_direction(-1.0f));
                        break;
                    }
                case "AF1":
                    if(dataObj.getFloat("value")!=null) {
                        weatherSenorDataPoints.setData(data.setRainfall(dataObj.getFloat("value")));
                        break;
                    }else {
                        weatherSenorDataPoints.setData(data.setRainfall(-1.0f));
                        break;
                    }
                case "AL1":
//                    getFloat方法默认会将空字串""转换为null
                    if(dataObj.getFloat("value")!=null) {
                        weatherSenorDataPoints.setData(data.setIllumination(dataObj.getFloat("value") * 1000));
                        break;
                    }else {
                        weatherSenorDataPoints.setData(data.setIllumination(-1.0f));
                        break;
                    }
                default:break;
            }
        }
        if(weatherSenorDataPoints.getData().getIllumination() == null){
            weatherSenorDataPoints.setData(data.setIllumination(-1.0f));
        }
        weatherSenorDataPoints.setData(data).setType(1);
        int i = deviceMapper.insertWeatherDataPoints(weatherSenorDataPoints);
        int j = deviceMapper.updateDevice(iotDeviceInfo);
        //更新所有设备表device_permi表
        permiMapper.updateByPrimaryKeySelective(devicePermiInfo);
        System.out.println("weatherSenorDataPoints:" + weatherSenorDataPoints + ",iotDeviceInfo:" + iotDeviceInfo);
        return i+j;
    }

    @Override
    public YSTYDeviceInfo selectYSTYDevice(String deviceId){
        return ystyDeviceMapper.selectYSTYDeviceById(deviceId);
    }

}
